package com.scalyze.apps.socialanyltics.classify;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.lucene.analysis.Analyzer;
import org.apache.mahout.classifier.BayesFileFormatter;
import org.apache.mahout.classifier.ClassifierResult;
import org.apache.mahout.classifier.bayes.algorithm.BayesAlgorithm;
import org.apache.mahout.classifier.bayes.common.BayesParameters;
import org.apache.mahout.classifier.bayes.datastore.InMemoryBayesDatastore;
import org.apache.mahout.classifier.bayes.exceptions.InvalidDatastoreException;
import org.apache.mahout.classifier.bayes.interfaces.Algorithm;
import org.apache.mahout.classifier.bayes.interfaces.Datastore;
import org.apache.mahout.classifier.bayes.model.ClassifierContext;
import org.apache.mahout.vectorizer.DefaultAnalyzer;

// TODO: Auto-generated Javadoc
/**
 * The Class Classifier.
 */
public class Classifier
{
    
    /** The context. */
    private ClassifierContext context;

    /** The algorithm. */
    private Algorithm algorithm;

    /** The datastore. */
    private Datastore datastore;

    /** The model directory. */
    private File modelDirectory;

    /** The analyzer. */
    Analyzer analyzer;

    /**
     * Instantiates a new amex classifier.
     */
    public Classifier()
    {
        analyzer = new DefaultAnalyzer();
    }

    /**
     * Inits the.
     *
     * @param basePath the base path
     * @throws FileNotFoundException the file not found exception
     * @throws InvalidDatastoreException the invalid datastore exception
     */
    public void init(File basePath) throws FileNotFoundException, InvalidDatastoreException
    {

        if (!basePath.isDirectory() || !basePath.canRead())
        {
            throw new FileNotFoundException(basePath.toString());
        }

        modelDirectory = basePath;

        algorithm = new BayesAlgorithm();
        BayesParameters p = new BayesParameters();
        p.set("basePath", modelDirectory.getAbsolutePath());
        p.setGramSize(1);
        datastore = new InMemoryBayesDatastore(p);
        context = new ClassifierContext(algorithm, datastore);
        context.initialize();
    }

    /**
     * Classify.
     *
     * @param mail the mail
     * @return the string
     * @throws IOException Signals that an I/O exception has occurred.
     * @throws InvalidDatastoreException the invalid datastore exception
     */
    public String classify(Reader mail) throws IOException, InvalidDatastoreException
    {
        String document[] = BayesFileFormatter.readerToDocument(analyzer, mail);
        ClassifierResult result = context.classifyDocument(document, "unknown");

        return result.getLabel();
    }

    public static void main(String args[]) throws InvalidDatastoreException, IOException
    {
        Classifier classifier = new Classifier();
        classifier.init(new File("/home/impadmin/source/twitterProject/scalytics/bayes-model"/*"/home/ubuntu/examples/classify-data/classify-data/bayes-model"*/));
        String line = null;
        
//        String[] files = { "/home/ubuntu/amextweets/1317126769854/big_data_amex_udf_partitioned/amexTweetsData",
//                "/home/ubuntu/amextweets/1317126769854/big_data_master_udf_partitioned/masterTweetsData",
//                "/home/ubuntu/amextweets/1317126769854/big_data_chase_card_udf_partitioned/chaseCardTweets",
//                "/home/ubuntu/amextweets/1317126769854/big_data_visa_card_udf_partitioned/visaTweetsData" };
        String[] files = {"/home/impadmin/tweet-export-18-dec/000000_0"};
        double yCounter,nCounter, nuCounter=0;
        Map<String, List<Long>> counterList = new HashMap<String, List<Long>>(); 
        for(String file : files)
        {
            yCounter=0.00;
            nCounter=0.00;
            nuCounter=0.00;
            BufferedReader reader = new BufferedReader(new FileReader(new File(/*"D:/vivek/source/SemanticAnalyzer/amexTweetsData"*/file)));
            BufferedWriter yFileWriter  = new BufferedWriter(new FileWriter(new File(file.substring(0, file.lastIndexOf("/"))+"/YES.txt")));
            BufferedWriter nFileWriter  = new BufferedWriter(new FileWriter(new File(file.substring(0, file.lastIndexOf("/"))+"/NO.txt")));
            BufferedWriter nuFileWriter = new BufferedWriter(new FileWriter(new File(file.substring(0, file.lastIndexOf("/"))+"/NU.txt")));
            while((line=reader.readLine()) !=null)
            {
                StringReader strReader = new StringReader(line);
                String classify = classifier.classify(strReader);
                if(classify.equals(Classfier.YES.name()))
                {
                    yFileWriter.write(classify + "\t"+line);
                    yFileWriter.newLine();
                    yCounter++;
                } else if(classify.equals(Classfier.NO.name()))
                {
//                    System.out.println("Got NO");
                    nFileWriter.write(classify + "\t"+line);
                    nFileWriter.newLine();
                    nCounter++;
                } else
                {
//                    System.out.println("Got NU");
                    nuFileWriter.write(classify + "\t"+line);
                    nuFileWriter.newLine();
                    nuCounter++;
                }
            }
            counterList.put(file.substring(file.lastIndexOf("/") + 1), calculatePercentage(yCounter, nCounter, nuCounter));
            yFileWriter.close();
            yFileWriter = null;
            nFileWriter.close();
            nFileWriter =null;
            nuFileWriter.close();
            nuFileWriter = null;
            reader.close();
        }
        System.out.println("done");
    }

    private static List<Long> calculatePercentage(double yCount, double nCount, double nuCount)
    {
        List<Long> lst = new ArrayList<Long>();
        double total = yCount + nCount + nuCount;
        if(total > 0)
        {
            lst.add(Math.round(Double.valueOf(yCount * 100/ total )));
            lst.add(Math.round(Double.valueOf(nCount * 100/ total )));
            lst.add(Math.round(Double.valueOf(nuCount * 100/ total )));
        }else {
            lst.add(0l);
            lst.add(0l);
            lst.add(0l);
            
        }
       return lst;
    }
 enum Classfier
 {
     YES,
     NO,
     NU
 }
}
